package com.ywh.composetest.activity

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandHorizontally
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.scaleIn
import androidx.compose.animation.shrinkHorizontally
import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.ywh.composetest.widget.BoxTextCompose
import com.ywh.composetest.widget.SpacerHorizontal
import com.ywh.composetest.widget.SpacerVertical

/**
 *
 * EnterTransition
 * AnimationSpec动画差值器:tween:补间动画规格，spring:弹跳动画规格，Keyframes:关键帧动画规格
 *
 *
 * animateColorAsState(targetValue = )
 * animateSizeAsState(targetValue = )
 * animateOffsetAsState(targetValue = )
 * animateDpAsState(targetValue = )
 * animateFloatAsState(targetValue = )
 * animateIntAsState(targetValue = )
 * animateValueAsState(targetValue = )
 *
 * AnimatedVisibility():
 *
 * Modifier.animateContentSize:在组件大小改变时执行动画
 *
 * Crossfade():AnimatedContent的一种，没法对尺寸变换进行渐变的，大小是突变，可以用AnimatedContent
 *
 * AnimatedContent:控制多个组件入场和出场
 *
 */
class AnimatableActivity : BaseComposeActivity() {
    val TAG = AnimatableActivity::class.java.simpleName

    @Composable
    override fun OnComposable(savedInstanceState: Bundle?) {
        val scrollState = rememberScrollState()
        Column(modifier = Modifier.verticalScroll(scrollState)) {

            AnimateColorAsStateCompose()

            SpacerVertical(height = 10.dp)

            AnimatedVisibilityTestCompose()

            SpacerVertical(height = 10.dp)

            AnimatedVisibilityWithAnimatedEnterExitTestCompose()

            SpacerVertical(height = 10.dp)

            AnimateContentSizeTestCompose()

            SpacerVertical(height = 10.dp)

            CrossfadeCompose()

            SpacerVertical(height = 10.dp)

            AnimatedContentCompose()
        }
    }

    @Composable
    private fun AnimatedContentCompose() {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            var showOne by remember {
                mutableStateOf(false)
            }

            BoxTextCompose(content = "两组件切换", backgroundColor = Color.Green) {
                showOne = !showOne
            }

            SpacerVertical(height = 10.dp)

            AnimatedContent(
                targetState = showOne,
                label = "AnimatedContent",
                transitionSpec = {
                    (fadeIn(animationSpec = tween(2200, delayMillis = 90)) +
                            scaleIn(
                                initialScale = 0.92f,
                                animationSpec = tween(2200, delayMillis = 90)
                            ))
                        .togetherWith(fadeOut(animationSpec = tween(90)))
                }) {
                if (it) {
                    BoxTextCompose(
                        content = "Crossfade1Crossfade1", backgroundColor = Color.Green
                    ) {

                    }
                } else {
                    BoxTextCompose(content = "Crossfade2", backgroundColor = Color.Red) {

                    }
                }
            }
        }
    }

    @Composable
    private fun CrossfadeCompose() {
        Column(horizontalAlignment = Alignment.CenterHorizontally) {
            var showOne by remember {
                mutableStateOf(false)
            }

            BoxTextCompose(content = "两组件切换", backgroundColor = Color.Green) {
                showOne = !showOne
            }

            SpacerVertical(height = 10.dp)

            Crossfade(targetState = showOne, label = "crossfade", animationSpec = tween(3500)) {
                if (it) {
                    BoxTextCompose(
                        content = "Crossfade1Crossfade1", backgroundColor = Color.Green
                    ) {

                    }
                } else {
                    BoxTextCompose(content = "Crossfade2", backgroundColor = Color.Red) {

                    }
                }
            }
        }
    }


    @Composable
    private fun AnimateContentSizeTestCompose() {
        var message by remember {
            mutableStateOf("Hello world")
        }
        Column {
            BoxTextCompose(content = "改变他的大小", backgroundColor = Color.Yellow) {
                if (message.length > 12) {
                    message = "Hello world"
                } else {
                    message += "，你好你好你好"
                }
            }

            SpacerVertical(height = 10.dp)

            Box(
                modifier = Modifier
                    .background(Color.Yellow)
                    .animateContentSize(
                        animationSpec = tween(2000),
                        finishedListener = { init, target ->
                            Log.e(TAG, "finishedListener:${init},${target}")
                        }), contentAlignment = Alignment.Center
            ) {
                Text(text = message)
            }
        }
    }


    /**
     * 希望每个子组件的动画不一样，可以在子组件设置自己的animateEnterExit
     */
    @OptIn(ExperimentalAnimationApi::class)
    @Composable
    private fun AnimatedVisibilityWithAnimatedEnterExitTestCompose() {
        var animatedVisibilityState by remember {
            mutableStateOf(true)
        }
        Row {
            AnimatedVisibility(
                visible = animatedVisibilityState,
                enter = fadeIn(tween(durationMillis = 2000)) + expandHorizontally(
                    tween(
                        durationMillis = 2000
                    )
                ),
                exit = fadeOut(tween(durationMillis = 2000)) + shrinkHorizontally(
                    tween(
                        durationMillis = 2000
                    )
                )
            ) {
                Column {
                    Box(
                        modifier = Modifier
                            .background(Color.Green)
                            .animateEnterExit(
                                enter = expandHorizontally(
                                    tween(
                                        durationMillis = 2000
                                    )
                                ), exit = shrinkHorizontally(
                                    tween(
                                        durationMillis = 2000
                                    )
                                )
                            ), contentAlignment = Alignment.Center
                    ) {
                        Text(text = "animateEnterExit\n2000")
                    }

                    SpacerVertical(height = 8.dp)
                    Box(
                        modifier = Modifier
                            .background(Color.Green)
                            .animateEnterExit(
                                enter = expandHorizontally(
                                    tween(
                                        durationMillis = 1000
                                    )
                                ), exit = shrinkHorizontally(
                                    tween(
                                        durationMillis = 1000
                                    )
                                )
                            ), contentAlignment = Alignment.Center
                    ) {
                        Text(
                            text = "animateEnterExit\n" + "1000"
                        )
                    }
                }
            }
            SpacerHorizontal(width = 10.dp)
            BoxTextCompose(content = "点我让他←隐藏") {
                val temp = animatedVisibilityState
                animatedVisibilityState = !temp
            }
        }
    }

    /**
     * AnimatedVisibility:visibility改变的动画
     */
    @Composable
    private fun AnimatedVisibilityTestCompose() {
        var animatedVisibilityState by remember {
            mutableStateOf(true)
        }
        Row {
            AnimatedVisibility(
                visible = animatedVisibilityState,
                enter = fadeIn(tween(durationMillis = 2000)) + expandHorizontally(
                    tween(
                        durationMillis = 2000
                    )
                ),
                exit = fadeOut(tween(durationMillis = 2000)) + shrinkHorizontally(
                    tween(
                        durationMillis = 2000
                    )
                )
            ) {
                BoxTextCompose(content = "AnimatedVisibility1", backgroundColor = Color.Yellow) {}
            }
            SpacerHorizontal(width = 10.dp)
            BoxTextCompose(content = "点我让他←隐藏", backgroundColor = Color.Yellow) {
                val temp = animatedVisibilityState
                animatedVisibilityState = !temp
            }
        }
    }


    @Composable
    private fun AnimateColorAsStateCompose() {
        var isBig by remember {
            mutableStateOf(false)
        }

        val color by animateColorAsState(
            targetValue = if (isBig) Color.Red else Color.Green,
            label = "color"
        )

        val dp by animateDpAsState(
            targetValue = if (isBig) 200.dp else 100.dp, label = "size"
        )
        Box(
            modifier = Modifier
                .size(dp)
                .background(color)
                .clickable {
                    isBig = !isBig
                }, contentAlignment = Alignment.Center
        ) {
            Text(text = "测试animateColorAsState")
        }
    }
}